package com.cardmanager.pro.business.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cardmanager.pro.business.CreditCardAccountBusiness;
import com.cardmanager.pro.business.CreditCardAccountHistoryBusiness;
import com.cardmanager.pro.pojo.CreditCardAccount;
import com.cardmanager.pro.pojo.CreditCardAccountHistory;
import com.cardmanager.pro.repository.CreditCardAccountRepository;
@Service
public class CreditCardAccountBusinessImpl implements CreditCardAccountBusiness {

	@Autowired
	private CreditCardAccountRepository creditCardAccountRepository;
	
	@Autowired
	private CreditCardAccountHistoryBusiness creditCardAccountHistoryBusiness;
	
	@Autowired
	private EntityManager em;
	
//	不缓存
	@Override
	public CreditCardAccount findByUserIdAndCreditCardNumberAndVersion(String userId, String creditCardNumber,String version) {
		em.clear();
		CreditCardAccount creditCardAccount = creditCardAccountRepository.findByUserIdAndCreditCardNumberAndVersion(userId, creditCardNumber,version);
		return creditCardAccount;
	}

	@Transactional
	@Override
	public CreditCardAccount save(CreditCardAccount creditCardAccount) {
		creditCardAccount = creditCardAccountRepository.saveAndFlush(creditCardAccount);
		em.clear();
		return creditCardAccount;
	}
	
//	不缓存
	@Override
	@Transactional
	/**
	 * addOrSub: 0:增加  1:减少blance增加freezeBlance 3:增加blance减少freezeBlance 4:减少freezeBlace
	 */
	public CreditCardAccount updateCreditCardAccountAndVersion(String userId,String creditCardNumber,String taskId,int addOrSub,BigDecimal amount,String description,String version){
		em.clear();
		CreditCardAccount creditCardAccount = this.findByUserIdAndCreditCardNumberAndVersion(userId, creditCardNumber,version);
		CreditCardAccountHistory creditCardAccountHistory = creditCardAccountHistoryBusiness.findByTaskIdAndAddOrSub(taskId,addOrSub);
		if(creditCardAccountHistory == null){
			if(creditCardAccount != null){
				if(0 == addOrSub || 5 == addOrSub){
					if (0 == addOrSub) {
						creditCardAccountHistory = creditCardAccountHistoryBusiness.findByTaskIdAndAddOrSub(taskId,5);
						if (creditCardAccountHistory != null) {
							BigDecimal amount2 = creditCardAccountHistory.getAmount();
							amount = amount.subtract(amount2);
						}
					}
					creditCardAccount.setBlance(creditCardAccount.getBlance().add(amount).setScale(2, BigDecimal.ROUND_HALF_UP));
					creditCardAccount.setLastUpdateTime(new Date());
					creditCardAccount = this.save(creditCardAccount);
					creditCardAccountHistoryBusiness.createNewHistory(addOrSub,amount,taskId,creditCardAccount.getId(),creditCardAccount.getBlance(),description);
				}else if(1 == addOrSub){
					creditCardAccount.setBlance(creditCardAccount.getBlance().subtract(amount).setScale(2, BigDecimal.ROUND_HALF_UP));
					creditCardAccount.setLastUpdateTime(new Date());
					creditCardAccount.setFreezeBlance(creditCardAccount.getFreezeBlance().add(amount));
					creditCardAccount = this.save(creditCardAccount);
					creditCardAccountHistoryBusiness.createNewHistory(addOrSub,amount,taskId,creditCardAccount.getId(),creditCardAccount.getBlance(),description);
				}else if(3 == addOrSub){
					if(creditCardAccount.getFreezeBlance().compareTo(amount) >= 0) {
						if (BigDecimal.ZERO.compareTo(amount) == 0) {
							CreditCardAccountHistory creditCardAccountHistory2 = creditCardAccountHistoryBusiness.findByTaskIdAndAddOrSub(taskId, 1);
							if (creditCardAccountHistory2 != null) {
								amount = creditCardAccountHistory2.getAmount();
							}
						}
						creditCardAccount.setBlance(creditCardAccount.getBlance().add(amount).setScale(2, BigDecimal.ROUND_HALF_UP));
						creditCardAccount.setLastUpdateTime(new Date());
						creditCardAccount.setFreezeBlance(creditCardAccount.getFreezeBlance().subtract(amount));
						CreditCardAccountHistory creditCardAccountHistoryAddOrSub1 = creditCardAccountHistoryBusiness.findByTaskIdAndAddOrSub(taskId, 1);
						if (creditCardAccountHistoryAddOrSub1 != null) {
							creditCardAccountHistoryAddOrSub1.setAddOrSub(7);
							creditCardAccountHistoryBusiness.save(creditCardAccountHistoryAddOrSub1);
						}
						creditCardAccount = this.save(creditCardAccount);
						creditCardAccountHistoryBusiness.createNewHistory(addOrSub+4,amount,taskId,creditCardAccount.getId(),creditCardAccount.getBlance(),description);
					}
				}else if(4 == addOrSub){
					creditCardAccount.setLastUpdateTime(new Date());
					creditCardAccountHistory = creditCardAccountHistoryBusiness.findByTaskIdAndAddOrSub(taskId,5);
					if (creditCardAccountHistory != null) {
						BigDecimal amount2 = creditCardAccountHistory.getAmount();
						creditCardAccount.setBlance(creditCardAccount.getBlance().subtract(amount2));
					}
					if(BigDecimal.ZERO.compareTo(creditCardAccount.getFreezeBlance()) == 0){
						creditCardAccount.setBlance(creditCardAccount.getBlance().subtract(amount));
					}else{
						creditCardAccount.setFreezeBlance(creditCardAccount.getFreezeBlance().subtract(amount));
					}
					creditCardAccount = this.save(creditCardAccount);
					creditCardAccountHistoryBusiness.createNewHistory(addOrSub,amount,taskId,creditCardAccount.getId(),creditCardAccount.getBlance(),description);
				}
			}else {
				throw new RuntimeException("更改账户失败!无账户信息!!!=====userId=" + userId + "=====creditCardNumber=" + creditCardNumber);
			}
		}
		return creditCardAccount;
	}

//	不缓存
	@Override
	public List<CreditCardAccount> findCreditCardAccountByBlanceNotZeroAndVersion(String version,Pageable pageable) {
		em.clear();
		Page<CreditCardAccount> pageAccount = creditCardAccountRepository.findCreditCardAccountByBlanceNotZeroAndVersion(version,pageable);
		List<CreditCardAccount> models = new ArrayList<>(pageAccount.getContent());
		return models;
	}

	@Override
	public List<CreditCardAccount> findByFreezeBlanceGreaterThan0AndVersion(String version) {
		em.clear();
		List<CreditCardAccount> models = creditCardAccountRepository.findByFreezeBlanceGreaterThan0AndVersion(version);
		return models;
	}

	@Override
	public CreditCardAccount findByCreditCardNumberAndVersion(String creditCardNumber,String version) {
		em.clear();
		CreditCardAccount creditCardAccount = creditCardAccountRepository.findByCreditCardNumberAndVersion(creditCardNumber,version);
		return creditCardAccount;
	}

	@Override
	public List<CreditCardAccount> findByFreezeBlanceAndVersion(BigDecimal amount,String version) {
		em.clear();
		List<CreditCardAccount> models = creditCardAccountRepository.findByFreezeBlanceAndVersion(amount,version);
		return models;
	}

	@Override
	public List<CreditCardAccount> findCreditCardAccountByBlanceLessTenAndVersion(String version,Pageable pageable) {
		em.clear();
		Page<CreditCardAccount> findCreditCardAccountByBlanceLessTen = creditCardAccountRepository.findCreditCardAccountByBlanceLessTenAndVersion(version,pageable);
		List<CreditCardAccount> models = new ArrayList<>(findCreditCardAccountByBlanceLessTen.getContent());
		return models;
	}

	@Override
	public List<CreditCardAccount> findByBlanceAndVersionAndLastUpdateTimeLessThan(BigDecimal blance, String version,
			Date time) {
		em.clear();
		return creditCardAccountRepository.findByBlanceAndVersionAndLastUpdateTimeLessThan(blance,version,time);
	}
	
}
